<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>ComObjQuery()</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link href="../static/theme.css" rel="stylesheet" type="text/css" />
<script src="../static/content.js" type="text/javascript"></script>
</head>
<body>

<h1>ComObjQuery() <span class="ver">[v1.0.96.00+]</span></h1>
<p>Queries a COM object for an interface or service.</p>
<pre class="Syntax">InterfacePointer := ComObjQuery(ComObject, [SID,] IID)</pre>

<h3>Parameters</h3>
<dl>

  <dt>ComObject</dt>
  <dd><p>A COM wrapper object or raw interface pointer.</p></dd>

  <dt>IID</dt>
  <dd><p>An interface identifier (GUID) in the form "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}".</p></dd>

  <dt>SID</dt>
  <dd><p>A service identifier in the same form as IID. When omitting this parameter, also omit the comma.</p></dd>

</dl>

<h3>General Remarks</h3>
<p>In its two-parameter mode, this function is equivalent to <a href="http://msdn.microsoft.com/en-us/library/ms682521.aspx">IUnknown::QueryInterface</a>. When SID and IID are both specified, it internally queries for the <a href="http://msdn.microsoft.com/en-us/library/cc678965.aspx">IServiceProvider</a> interface, then calls <a href="http://msdn.microsoft.com/en-us/library/cc678966.aspx">IServiceProvider::QueryService</a>. In either case, the return value is either zero or a pointer to the requested interface. Generally this pointer must be <a href="ObjAddRef.htm">released</a> when the script is finished with it.</p>

<h3>Related</h3>
<a href="ObjAddRef.htm">ObjRelease</a>, <a href="ComObjCreate.htm">ComObjCreate</a>, <a href="ComObjGet.htm">ComObjGet</a>, <a href="ComObjActive.htm">ComObjActive</a>, <a href="ComObjError.htm">ComObjError</a>

<h3>Examples</h3>

<pre id="ExClassName" class="NoIndent"><em>; Example: Determine the class name of an object.</em>

obj := ComObjCreate("Scripting.Dictionary")

MsgBox % "Interface name: " ComObjType(obj, "name")

IID_IProvideClassInfo := "{B196B283-BAB4-101A-B69C-00AA00341D07}"

<em>; Request a pointer to the object's IProvideClassInfo interface.</em>
if !(pci := ComObjQuery(obj, IID_IProvideClassInfo))
{
    MsgBox IProvideClassInfo interface not supported.
    return
}

<em>; Call GetClassInfo to retrieve a pointer to the ITypeInfo interface.</em>
DllCall(vtable(pci, 3), "ptr", pci, "ptr*", ti)

<em>; Call GetDocumentation to get the object's full type name.</em>
DllCall(vtable(ti, 12), "ptr", ti, "int", -1, "ptr*", name, "ptr", 0, "ptr", 0, "ptr", 0)

<em>; Convert the BSTR pointer to a usable string.</em>
name := StrGet(name, "UTF-16")

<em>; Release raw interface pointers.</em>
ObjRelease(ti)
ObjRelease(pci)

<em>; Display the type name!</em>
MsgBox % "Class name: " name

vtable(ptr, n) {
    <em>; NumGet(ptr+0) returns the address of the object's virtual function
    ; table (vtable for short). The remainder of the expression retrieves
    ; the address of the nth function's address from the vtable.</em>
    return NumGet(NumGet(ptr+0), n*A_PtrSize)
}
</pre>

<pre id="ExIE" class="NoIndent"><em>; Example: Automate an existing Internet Explorer window.</em>

sURL := "http://ahkscript.org/boards/"
if webBrowser := GetWebBrowser()
   webBrowser.Navigate(sURL)
return

GetWebBrowser()
{
    <em>; Get a raw pointer to the document object of the top-most IE window.</em>
    static msg := DllCall("RegisterWindowMessage", "str", "WM_HTML_GETOBJECT")
    SendMessage msg, 0, 0, Internet Explorer_Server1, ahk_class IEFrame
    if ErrorLevel = FAIL
        return  <em>; IE not found.</em>
    lResult := ErrorLevel
    DllCall("oleacc\ObjectFromLresult", "ptr", lResult
        , "ptr", GUID(IID_IHTMLDocument2,"{332C4425-26CB-11D0-B483-00C04FD90119}")
        , "ptr", 0, "ptr*", pdoc)
    
    <em>; Query for the WebBrowserApp service. In this particular case,
    ; the SID and IID are the same, but it isn't always this way.</em>
    static IID_IWebBrowserApp := "{0002DF05-0000-0000-C000-000000000046}"
    static SID_SWebBrowserApp := IID_IWebBrowserApp
    pweb := ComObjQuery(pdoc, SID_SWebBrowserApp, IID_IWebBrowserApp)
    
    <em>; Release the document object pointer.</em>
    ObjRelease(pdoc)
    
    <em>; Return the WebBrowser object, wrapped for usability:</em>
    static VT_DISPATCH := 9, F_OWNVALUE := 1
    return ComObject(VT_DISPATCH, pweb, F_OWNVALUE)
}

GUID(ByRef GUID, sGUID) <em>; Converts a string to a binary GUID and returns its address.</em>
{
    VarSetCapacity(GUID, 16, 0)
    return DllCall("ole32\CLSIDFromString", "wstr", sGUID, "ptr", &amp;GUID) >= 0 ? &amp;GUID : ""
}
</pre>

</body>
</html>
